//该版本为同花顺云条件单版本，需要有特定券商支持
var is_auto_submit = 0;//这里填1表示开启全自动提交并且买入，慎用，风险自负
var customMoney = 0;//用户自定义网格一网的金额，不熟悉网格不要设置

/*缓存操作*/
app.cache = {
    key: 'auto_trade_mata',
    storage: storages.create('hexin'),
    get: function () {
        return this.storage.get(this.key)
    },
    set: function (value) {
        return this.storage.put(this.key, value), true
    },
    clear: function () {
        app.autoMata = (void 0)
        return this.storage.remove(this.key), true
    },
    token: function(token){
        const tokenKey = 'auto_trade_token'
        return token == undefined ? this.storage.get(tokenKey):(this.storage.put(tokenKey, token), true) 
    },
    config:{
        /*窗口坐标*/
        btnTitle: '点击自动执行交易', windowX: 150, rawY: 0, downTime: 0,
        /*执行状态：0停止、1启动*/
        state: 0, 
        version: 'v1.0.1',
        updateRecords: [
            '1.【新增】创建后回退到初始页面',
            '2.【新增】自动识别账户条件单数量 并提示风险',
            '3.【新增】根据自定义代码配置条件单',
        ],
        downloadInfo: ['同花顺自动交易条件单.js', 'https://www.souin.cn/autoTrade1.js'],
    },
}

var site =  'https://www.souin.cn'

/*自动交易所需要的元数据结构*/
app.autoMata = app.cache.get() || {
    website: `https://www.souin.cn`,
    windowY: 0,         // 设置窗口固定高度位置
    profitRate: 0,         // 一键清仓盈亏比设置
    autoSubmit: is_auto_submit,  
    stocks: [-1], //股票
    funds:  [-1], //基金
    bonds:  [-1], //债券
    data: {
        bc: 0,          //步长
        num: 0,         //委托数量
        buy_num: 0,     //购买数量
        cacheType: '',  //stock:股票、fund:基金、bond:债券
        code: '',       //股票、基金、债券代码
        name: ' ',      //股票名称
        price: 0,       //基准价格
        low: 0,         //最低价格
        high: 0,        //最高价格
        date: '',       //策略日期
    }
}

//异常时代码回滚处理的参数
var currentStock = 0;
var currentType = '';
var back_times=0;//返回次数检测返回是否异常
//用户自定义代码
var customStock = '';
//用户亏损持仓列表
var kschicang_list = {}
//构造亏损代码列表
var ks_codelist = []

/*当前不在同花顺界面时弹窗*/
currentPackage() !== "com.hexin.plat.android" && launchApp("同花顺") && sleep(1000)
/*操作窗口->程序入口*/
window = floaty.rawWindow(
    <frame w="{{device.width-(app.cache.config.windowX*2)}}px">
        <horizontal>
            <button id="ok" text="{{app.cache.config.btnTitle}}" w="*" alpha="0.8" style="Widget.AppCompat.Button.Colored"/>
        </horizontal>
    </frame>
)

window.setPosition(app.cache.config.windowX, app.autoMata.windowY||0)
var profitRate = app.autoMata.profitRate || 0
var sync_iscompelte = false;//下拉是否完成
var sync_cond_iscompelte = false;//条件单下拉是否完成
window.ok.setOnTouchListener(function (view, event) {
    if (event.getAction() == event.ACTION_DOWN) {
        app.cache.config.rawY = event.getRawY()
        app.cache.config.downTime = new Date().getTime()
    }else if (event.getAction() == event.ACTION_UP) {
        if (Math.abs(event.getRawY() - app.cache.config.rawY) < 10 && (new Date().getTime() - app.cache.config.downTime) <= 150) {
            /*点击事件*/
            if (app.cache.config.state == 0) {
                app.cache.config.state = 1
                threads.start(function () {
                    try {
                        changeTitle(1) && sleep(800)
                        if (validateToken()) {
                            // 判断当前是否是交易菜单栏界面
                            !text('云条件单').boundsInside(0, device.height/2, device.width, device.height).exists() && click('交易')
                            // 服务端传来的策略有效且当月策略未创建过条件单
                            if (getStrategyData() && checkHistoryData()) {
                                clickConditionOrderByUI(1)
                            }
                        }
                        changeTitle(100)
                    } catch (err) {
                        log('网格自动化交易程序异常：', err)
                        changeTitle(102)
                        backStorageStock()
                    }
                    app.cache.config.state = 0
                    //界面回退至初始界面
                    back_click()
                })
            
            } else {
                app.cache.config.state = 0    
                changeTitle(101)
                backStorageStock()
                threads.shutDownAll()
            }
        }else if (app.cache.config.state == 0 && Math.abs(event.getRawY() - app.cache.config.rawY) < 10 && (new Date().getTime() - app.cache.config.downTime) > 150) {
            dialogs.select('功能&设置', [`窗口位置Y: ${app.autoMata.windowY}`, '清除缓存(Clear)', '更新授权码(Token)', '检查更新(Check)', '自定义代码配置条件单','条件单一键呵护功能', `一键清仓盈利大于${profitRate}%产品`,'退出(Exit)']).then(i => {
                i+1 == 1 && rawInput("设置窗口与屏顶位置(250-270)", 250).then(val => {
                    if (val!='' && val!=undefined) {
                        app.autoMata.windowY = Number(val)
                        window.setPosition(app.cache.config.windowX, app.autoMata.windowY)
                        app.cache.set(app.autoMata)
                    }
                })
                i == 1 && app.cache.clear() && alert('今日缓存已清空！')
                i == 2 && rawInput("请输入您的授权码", app.cache.token()).then(token => {
                    token && app.cache.token(token)
                })
                i == 3 && onlineCheckUpdate()
                if (i == 4) {
                    rawInput("输入您想要配置的代码!", '').then(val => {
                        threads.start(function () {
                            try {
                                if (val!='' && val!=undefined) {    
                                    //自定义代码赋值
                                    customStock = val
                                    changeTitle(1) && sleep(800)
                                    if (validateToken()) {
                                        // 判断当前是否是交易菜单栏界面
                                        !text('云条件单').boundsInside(0, device.height/2, device.width, device.height).exists() && click('交易')
                                        // 服务端传来的策略有效且当月策略未创建过条件单
                                        if (getStrategyData() && checkHistoryData()) {
                                            clickConditionOrderByUI(0)
                                        }
                                    }
                                    changeTitle(100)
                                }
                
                            } catch (err) {
                                log('网格自动化交易程序异常：', err)
                                changeTitle(102)
                                backStorageStock()
                            }
                            back_click()
                        })
                    })
                }
                if (i == 5) {    
                    threads.start(function () {
                        deal_need_update_stock()
                    })
                }
                i == 7 && exit()
                if (i == 6){
                    rawInput("一键清仓盈利大于XX的产品，确认后将立即执行，请谨慎使用!", profitRate).then(val => {
                        threads.start(function () {
                            try {
                                if (val!='' && val!=undefined) {
                                    app.autoMata.profitRate = Number(val)
                                    app.cache.set(app.autoMata)
                                    if (confirm("是否执行清仓盈利大于"+ app.autoMata.profitRate+"%的操作?")){
                                        app.cache.config.state = 1
                                        clear_stocks()
                                        changeTitle(100)
                                    }else{
                                        print("取消了操作")
                                    }
                                }
                
                            } catch (err) {
                                log('网格自动化交易程序异常：', err)
                                changeTitle(102)
                            }
                            app.cache.config.state = 0
                        })
                    })
             
                }
            })
        }
    }
    return true
})
/*保持窗口线程一直活跃*/
setInterval(()=>{}, 1000)


//////////////////////以下为自动交易中调用的函数//////////////////////
/*校验Token是否存在*/
function validateToken(){
    let token = app.cache.token()
    if (!token) {
        token = rawInput("请输入您的注册码，致亿科技公众号点击基金通自动交易获取")
        if (!token) return false
        app.cache.token(token)
    }
    return true
}

/*改变标题状态*/
function changeTitle(type) {
    ui.run(function () {
        const {allMoney, stockMoney, data: {cacheType, code, price, high, low, bc, num}} = app.autoMata
        if (type === 1) window.ok.setText('开始执行,请勿操作屏幕...')
        else if (type === 2) window.ok.setText('正在获取服务端交易策略...')
        else if (type === 3) window.ok.setText(`策略类型:${cacheType=='bond'?'债券':cacheType}\t\t代码:${code}`)
        else if (type === 4) window.ok.setText(`策略类型:${cacheType=='bond'?'债券':cacheType}\t\t代码:${code}\n执行配置条件单...`)
        else if (type === 5) window.ok.setText(`配置条件单->1.设置监控条件\n价格区间:${low}-${high}\n初始价:${price} 数量:${num}`)
        else if (type === 6) window.ok.setText(`配置条件单->2.设置委托单\n步长:${bc}\t\t数量:${num}`)
        else if (type === 7) window.ok.setText(`配置条件单->3.确认提交\n总资产${allMoney}\t\t余额:${(allMoney-stockMoney).toFixed(2)}`)
        else if (type === 8) window.ok.setText(`配置条件单->4.自动下单`)
        else if (type === 100) window.ok.setText('自动交易执行完毕!')
        else if (type === 101) window.ok.setText('已停止交易执行!')
        else if (type === 102) window.ok.setText('程序异常被终断!')
        else if (type === 103) window.ok.setText('清仓中，请勿操作屏幕')
        else if (type === 104) window.ok.setText('自动调整条件单->仓位检查')
        else if (type === 105) window.ok.setText('自动调整条件单->条件单延期')
        else if (type === 106) window.ok.setText('自动调整条件单->暂停条件单')
        else if (type === 107) window.ok.setText('自动调整条件单->重新调整网格配置')
        else if (type === 108) window.ok.setText('自动调整条件单')
    })
    return true
}

/*获取服务器自动交易策略数据*/
function getStrategyData(){
    changeTitle(2)
    // 获取账号可用余额: 总资产-总市值
    const account = []
    boundsInside(0, device.height*0.2, device.width, device.height*0.4).className('TextView').depth(4).find().forEach(child=>{
        const value = child.text().trim().replace(',','')
        if (/^(0|[1-9]\d*)(\.\d{1,2})?$/.test(value)) {
            account.push(value)
        }
    })
    app.autoMata.allMoney = account[0]
    app.autoMata.stockMoney = account[1]
    const balance = account[0] - account[1]
    const {website, stocks, funds, bonds} = app.autoMata
    const token = app.cache.token()

    var label = findLabelWithText("条件监控中")[0]
    var Conditions_num=0
    if (label) {
        Conditions_num = parseInt(label.text().match(/\d+/g)[0]);
    } else {
        print("当前未配置条件单");
    }
    
    var calMoney = 2000
    if (customMoney > 2000){
        calMoney = customMoney
    }
    //根据条件单数量提示用户当前继续配置条件单是否有风险
    if (balance < 2 * Conditions_num * calMoney) {
        alert("系统检测到您当前条件单数量可能已经超过资金所能承受的范围，继续配置可能有风险")
    }
    const url = `${website}/stock/trade/autoChanceInTrade?code=${token}&stock=${stocks},${funds},${bonds}&m=${balance}&customMoney=${customMoney}&customCode=${customStock}&m1=${account[0]}&m2=${account[1]}`
    const {statusCode, body} =  http.get(url)
    if (statusCode == 200) {
        const {code, msg, data} = body.json()
        if(code > 0) {
            alert(msg)
            if (code == 30002) {
                // 删除无效注册码并显示注册码输入框
                app.cache.token('') && validateToken()
            }
            return false
        }
        return app.autoMata.data = Object.assign({}, app.autoMata.data, data)
    }
}


/*从缓存中检测是否存在历史条件单数据(确保当月策略不重复)*/
function checkHistoryData(){
    changeTitle(3)
    log('打印服务端交易策略明细->', app.autoMata)
    const {stocks, funds, bonds, data: {cacheType, date, code}}= app.autoMata
    // 判断是服务器策略是哪种交易种类：股票、基金、债券
    let isExists = false
    if (cacheType == "stock") {
        app.autoMata.stocks = stocks.includes(date)?stocks:[-1, date]
        !(isExists = app.autoMata.stocks.includes(code)) && app.autoMata.stocks.push(code)
    }else if(cacheType == "fund"){
        app.autoMata.funds = funds.includes(date)?funds:[-1, date]
        !(isExists = app.autoMata.funds.includes(code)) && app.autoMata.funds.push(code)
    }else if(cacheType == "bond"){
        app.autoMata.bonds = bonds.includes(date)?bonds:[-1, date]
        !(isExists = app.autoMata.bonds.includes(code)) && app.autoMata.bonds.push(code)
    }
    currentStock = code
    currentType = cacheType
    if (isExists) {
        alert('条件单策略已存在。\n程序已停止执行！')
        return false
    }
    return true
}

/*在UI组件上点击条件单，自定义的代码就不在下单*/
function clickConditionOrderByUI(type){
    changeTitle(4)
    const {code, price, low, high, bc, num, buy_num, cacheType, name} = app.autoMata.data
    click('云条件单') && sleep(random(500, 800)) || click('新建云条件单')
    click('网格-到价触发') && sleep(random(500, 800))
    click(desc('搜索输入框').findOne().bounds()) && setText(code.substring(0,1)) && sleep(300)
    code.substring(1).split('').forEach(c=>{
        input(c) && sleep(random(200, 250))
    })
    if(id("stock_search_editview").exists()){
        if(cacheType == "bond"){
            //债券点击代码
            clickCent(text(code),1000);
        } else if (cacheType == "stock") {    
            //股点击名称
            clickCent(text(name),1000);
        } else if(cacheType == "fund"){
            clickCent(text(code),1000);
        }  
    }

    // 配置网格到价触发条件单
    settingMonitorCondition(price, low, high, bc)
    settingTradeOrder(bc, num)
    confirmOrderBeforeSubmit(bc,buy_num)
    // 自动下单
    if(type!=0)
        doAutoSubmit(app.autoMata)
    else 
        doAutoSubmit2()
}

/*网格配置第一步监控条件*/
function settingMonitorCondition(price, low, high, bc){
    // 等待进入监控条件界面
    text('监控条件').waitFor()
    changeTitle(5)
    const curPrice = id("com.hexin.plat.android:id/tv_stock_price").findOne().text()
    if (Math.abs((curPrice - price) / price) > 0.015) {
        alert('价格偏差较大')
        return false
    }else{
        text('最低价(元)').setText(low) || text('最高价(元)').setText(high) || text("价格(元)").setText(price)
        click(text('按价格').findOnce().bounds()) && sleep(random(500, 800))
        clickRadioByText('回落卖出') && sleep(300) || clickRadioByText('反弹买入') && sleep(random(500, 800))
        setPriceByText('上涨-', bc) && sleep(random(300, 500))
        setPriceByText('回落-卖出', bc/10) && sleep(random(300, 500))
        setPriceByText('下跌-',  bc) && sleep(random(300, 500))
        setPriceByText('反弹-买入', bc/10) && sleep(random(300, 500))
        click('下一步') && sleep(random(800, 1000)) 
        return true
    }
}

/*网格配置第二步委托单*/
function settingTradeOrder(bc, num){
    // 等待进入委托单界面
    text('委托单').waitFor()
    changeTitle(6)
    clickCent(id("com.hexin.plat.android:id/switch_buy_fudong"),600);
    clickCent(id("com.hexin.plat.android:id/switch_sell_fudong"),600);
    //clickRadioByText('买入上浮') && clickRadioByText('卖出下浮') && sleep(random(800, 1000))
    text("请输入上浮价格").setText(bc/10)
    text("请输入下浮价格").setText(bc/10)
    //自动判断用户交易模式 如果金额模式自动切换成数量
    var chanege_btn= id("com.hexin.plat.android:id/tv_wt_type_change").findOne()
    var lay_out= id("com.hexin.plat.android:id/price_num_change_layout").findOne()
    var btn_text=chanege_btn.getText()
    if (btn_text=="数量"){
        print("切换数量成功")
        lay_out.click();
    }
    sleep(random(300, 500)) || text("请输入委托数量").setText(num)
    clickRadioByText('倍数委托') && text('好的').exists() && click('好的')
    click("提交云条件单") && sleep(random(800, 1000))
    return true
}

/*网格配置第三步条件单确认*/
function confirmOrderBeforeSubmit(bc,buy_num) {
    // 等待进入条件单确认界面
    text('云条件单确认').waitFor()
    changeTitle(7)
    const condition_info = textStartsWith('价格区间：').findOne().text()
    const price = condition_info.match("基准价：([0-9\.]*?)元")[1],
    low = condition_info.match("价格区间：([0-9\.]*?)元-")[1],
    high = condition_info.match("元-([0-9\.]*?)元；")[1],
    sz_str = condition_info.match("每上涨([0-9\.]*?)元")[1],
    hl_str = condition_info.match("回落([0-9\.]*?)元")[1],
    xd_str = condition_info.match("每下跌([0-9\.]*?)元")[1],
    ft_str = condition_info.match("反弹([0-9\.]*?)元")[1]

    if (price == null || low == null || high == null || sz_str == null ||
        hl_str == null || xd_str == null || ft_str == null) {
        print("参数异常，请取消提交");
        toast("参数异常，请勿提交");
        back_click();
        return false
    }
    if (sz_str != bc || xd_str != bc) {
        print("步长错误，请勿提交");
        toast("关键数据错误，请勿提交");
        back_click();
        return false
    }
    // 缓存策略
    return app.cache.set(app.autoMata), true
}

/*自动下单逻辑*/
function doAutoSubmit() {
    changeTitle(8) && sleep(300)
    log('打印服务端交易策略明细->', doSubmit)
    const {autoSubmit, data: {buy_num, cacheType, code}} = app.autoMata
    // true：自动提交订单 false：手动确认
    const doSubmit = is_auto_submit || confirm("您要提交条件单吗?")    
    if (doSubmit) {
        clickCent(id("com.hexin.plat.android:id/tv_confirm_submit"), 1200);// 最后提交功能 
        sleep(500)
        if(id("com.hexin.plat.android:id/tv_confirm_submit").exists()){
            text1 = id("com.hexin.plat.android:id/tv_confirm_submit").findOne().text()
            if (text1 == "重新提交"){
                return
            }
        }
    }       
    if (buy_num > 0) {
        waitClick(text(code));
        sleep(600);
        if (cacheType == "bond"){
            waitClick(id("com.hexin.plat.android:id/fangdai"));
        } else {
            waitClick(id("com.hexin.plat.android:id/xiadan"));
        }
        sleep(300);
        waitClick(id("com.hexin.plat.android:id/buy_button"));
        sleep(300);
        findClick(text("买入数量"));
        setText(1, buy_num);
        sleep(600);
        //text("买入数量").findOne().setText(1000);
        waitClick(text("买 入"));
        sleep(600);
        // true：自动提交订单 false：手动确认
        const doBuy = is_auto_submit || confirm("您确认下单吗?")
        if (doBuy) {
            waitClick(text("确定买入"))
        }
    }
}

/*自定义自动下单逻辑*/
function doAutoSubmit2() {
    changeTitle(8) && sleep(300)
    log('打印服务端交易策略明细->', doSubmit)
    const {autoSubmit, data: {buy_num, cacheType, code}} = app.autoMata
    // true：自动提交订单 false：手动确认
    const doSubmit = is_auto_submit || confirm("您要提交条件单吗?")    
    if (doSubmit) {
        clickCent(id("com.hexin.plat.android:id/tv_confirm_submit"), 1200);// 最后提交功能 
        sleep(500)
        if(id("com.hexin.plat.android:id/tv_confirm_submit").exists()){
            text1 = id("com.hexin.plat.android:id/tv_confirm_submit").findOne().text()
            if (text1 == "重新提交"){
                return
            }
        }
    }       
}


function clickRadioByText(content) {
    const btnBounds = text(content).findOnce().bounds()
    return click(btnBounds.centerX(), btnBounds.centerY()-45)
}

function setPriceByText(title, price){
    const uiBounds = text(title).findOnce().bounds()
    className('EditText').boundsInside(uiBounds.left, uiBounds.top, device.width, uiBounds.bottom).setText(price)
    return true
}

var sell_list =[]
var last_target =[]

function sell(){
    for (let [key, value] of Object.entries(sell_list)) {
    var auto_stockcode=id("com.hexin.plat.android:id/auto_stockcode").findOne()
    auto_stockcode.setText(key)
    auto_stockcode.click()
    sleep(500)
    click(value)&&sleep(500)
    print("key",key," value",value)
    sleep(300);
    click('全仓')&&sleep(500)
    var btn_sell_2 = id("btn_transaction").findOne()
    findson_click(btn_sell_2)&&sleep(500)
    var id_scroll=id("com.hexin.plat.android:id/content_scroll").findOne().children()
    var frist_txt =id_scroll[0].text()
    // print("frist_txt  ",frist_txt)
    sleep(500)
    if (frist_txt=='委托数量必须大于0'){//已经空仓不用管
        // print("之前已经售出")
        click('确定')&&sleep(500)
    }else{
        // print("售出中")
        var ok_btn=text('确认卖出').findOne();
        ok_btn.click()&&sleep(500)
        click('确定')&&sleep(500)
    }
    }
    toastLog("全部已售出")
    last_target=NaN
}


//获取持仓并构造持仓json
function deal_need_update_stock() {
    changeTitle(104)
    !text('条件单').boundsInside(0, device.height / 2, device.width, device.height).exists() && click('交易') && sleep(500)
    id("menu_holdings").findOne().click() && sleep(3000)
    while (true) {
        rollview = id("recyclerview_id").className("androidx.recyclerview.widget.RecyclerView").scrollable(true);
        if (!rollview.exists()) { //
            toastLog("持仓已经检查到最底部");
            sync_iscompelte = true;
        }
        //获取持仓数量
        var chicang = className("android.widget.TextView").text("持仓/可用").findOne()
        chicang_left = chicang.bounds().left
        //获取成本和现价
        var price_txt = className("android.widget.TextView").text("成本/现价").findOne()
        price_left = price_txt.bounds().left
        //获取盈亏
        var phase = className("android.widget.TextView").text("盈亏")
        if (phase.exists() == false) {
            var phase = className("android.widget.TextView").text("盈亏比")
        }
        phase = phase.findOne()
        phase_left = phase.bounds().left
        var stockcode_txt = className("android.widget.TextView").text("证券代码").findOne()
        stockcode_left = stockcode_txt.bounds().left
        id("recyclerview_id").findOne().children().forEach(child => {
            var target_content_c = child.findOne(id("content_scrollview"))
            if (target_content_c) {
                needgetchicang = true //只获取第一个值
                chichang_num = 0
                chengben = 0
                xianjia = 0
                stock_code = ''
                stock_name = ''
                target_content_c.children().forEach(child2 => {
                    if (needgetchicang && chicang_left == child2.bounds().left) {
                        //获取持仓
                        chichang_num = child2.text()
                        needgetchicang = false
                    }
                    //获取成本
                    else if (chengben == 0 && price_left == child2.bounds().left) {
                        chengben = child2.text()
                    }
                    //获取现价
                    else if (xianjia == 0 && chengben != 0 && price_left == child2.bounds().left) {
                        xianjia = child2.text()
                    }
                    //获取代码
                    else if (stockcode_left == child2.bounds().left) {
                        stock_code = child2.text()
                    }
                });
                //构造json
                kschicang_list[stock_code] = { 'num': chichang_num, 'cb': chengben, 'price': xianjia, isneed_adj:true }
                //构造亏损代码列表
                ks_codelist.push(stock_code)
            } else {
                sync_iscompelte = true;
            }

        });

        if (!sync_iscompelte) {
            swipeUp();
        } else {
            break;
        }
    }

    if (kschicang_list.length == 0) {//
        print("系统检测您不需要调整条件单")
    } else {
        print("updatelist ", ks_codelist)
        update_stock_cond()//修改需要调整的条件单
    }

    return true
}

//自动修改网格条件单 包括延期 跌破区间的处理 和删除
function update_stock_cond() {
    sync_iscompelte = false
    click('交易') && sleep(500)
    click('条件单') && sleep(random(500, 800)) || click('我的条件单')
    sleep(3000)
    day = null
    //保存无仓位列表
    no_hold = []
    //用来判断结束
    deal_code = []
    var count=0

    get_code = []
    while (true) {
        rollview = id("recyclerview").className("androidx.recyclerview.widget.RecyclerView").scrollable(true);
        get_code=[]
        count++
        if (rollview.exists() && (!deal_code.includes(get_code)||count<1)) {
            id("recyclerview").className("androidx.recyclerview.widget.RecyclerView").scrollable(true).findOne().children().forEach(child => {
                code_target = child.findOne(id("stockcode"))
                changeTitle(108)
                if (code_target) {
                    count=deal_code.length

                    var code = code_target.text()
                    if (!deal_code.includes(code)) {
                        deal_code.push(code)
                    }
                    if(count>2){
                        get_code.push(code)
                    }
                   
                    // log('-------------',ks_codelist)
                    //如果在亏损列表里面就要点进去检查
                    if (ks_codelist.includes(code) && (kschicang_list[code].isneed_adj == true)) {
                        kschicang_list[code].isneed_adj = false;
                        //点击进入详情页
                        code_target.parent().click();
                        sleep(800)
                        if (kschicang_list[code].num == 0) {
                            //没有持仓就暂停
                            pause_cond()
                        } else {
                            const condition_info = textStartsWith('价格区间：').findOne().text()
                            const price = condition_info.match("基准价：([0-9\.]*?)元")[1],
                                low = condition_info.match("价格区间：([0-9\.]*?)元-")[1]
                            //如果当前价已经小于价格区间的下限，则需要修改
                            if (parseFloat(kschicang_list[code].price) < parseFloat(low)) {
                                changeTitle(107)
                                paramPrice = kschicang_list[code].price
                                paramCb = kschicang_list[code].cb
                                paramNum = kschicang_list[code].num
                                token = app.cache.token()
                                const url = `${site}/stock/trade/getNewAutoCondData?code=${token}&stock_code=${code}&price=${paramPrice}&cb=${paramCb}&num=${paramNum}`
                                var res = http.get(url);
                                if (res.statusCode == 200) {
                                    updateData = JSON.parse(res.body.string());
                                    if (parseInt(updateData.code) > 0) {
                                        alert(updateData.msg);
                                        return false;
                                    }
                                    id("com.hexin.plat.android:id/edit_layout").findOne().click() && sleep(1000)
                                    do_update_cond(updateData)
                                    
                                } else {
                                    toast("请求失败:" + res.statusMessage);
                                    return false;
                                }
                            } else {
                                var cond_day_text = id("com.hexin.plat.android:id/condition_deadline").findOne().text()
                              
                                if(cond_day_text!=null){
                                    var days= cond_day_text.match("([0-9\-]*?)截止")
                                    if(days!=null && days.length>0){
                                        cond_day = days[1]
                                        if (day != null && cond_day == day) {
                                            //如果日期相等则点击取消返回列表页
                                            id("com.hexin.plat.android:id/title_bar_img").findOne().parent().click();
                                            sleep(600);
                                        }
                                    } else {
                                        var longDay= cond_day_text.match("长期有效")
                                        if(longDay!=null && longDay.length>0){
                                            id("com.hexin.plat.android:id/title_bar_img").findOne().parent().click();
                                            sleep(800)
                                        }else{
                                            changeTitle(105)
                                            id("com.hexin.plat.android:id/edit_layout").findOne().click() && sleep(1000)
                                            click('下一步') && sleep(random(800, 1000))
                                            click("提交云条件单") && sleep(random(800, 1000))
                                            const day_info = id("com.hexin.plat.android:id/tv_confirm_validity_time_end").findOne().text()
                                            var dayEdi=day_info.match("([0-9\-]*?)截止")
                                            if(dayEdi!=null && dayEdi.length>0){
                                                day = dayEdi[1]
                                            }
                                           
                                            clickCent(id("com.hexin.plat.android:id/tv_confirm_submit"), 1200);// 最后提交功能 
                                            sleep(800)
                                        }
                                        
                                    }
                                   
                                }
                               
                            }
                        }
                    } else {
                        if (!ks_codelist.includes(code) && !no_hold.includes(code)) {
                            no_hold.push(code)
                            code_target.parent().click();
                            pause_cond()
                        }
                    }
                }
               
                var target = child.findOne(id("conditionorder_common_disclaimer_text_view"));
                if (target) {
                    toastLog("条件单调整完成 ");
                    changeTitle(100)
                    sync_cond_iscompelte = true;
                }
            });
        } else {
            sync_cond_iscompelte = true;
        }
        sleep(2000)
        if (!sync_cond_iscompelte) {
            swipeUp();
            sleep(500)
        } else {
            break;
        }
    }
    id("com.hexin.plat.android:id/title_bar_img").findOne().parent().click();
}

//暂停条件单
function pause_cond() {
    sleep(800)
    changeTitle(106)
    //没有持仓就删除
    var pause_text = id("com.hexin.plat.android:id/delete").findOne().text()
    if (pause_text == '删除') {
        id("com.hexin.plat.android:id/delete_layout").findOne().click() && sleep(1000)
        id("com.hexin.plat.android:id/btn_positive").findOne().click() && sleep(1000)
    }
    id("com.hexin.plat.android:id/title_bar_img").findOne().parent().click() && sleep(1000)
}

//修改条件单
function do_update_cond(updateData) {
    price = updateData.data.price
    bc = updateData.data.bc
    const curPrice = id("com.hexin.plat.android:id/tv_stock_price").findOne().text()
    if (Math.abs((curPrice - price) / price) > 0.015) {
        alert('价格偏差较大')
        return false
    } else {
        id("et_price_section_min").findOne().setText(updateData.data.low) && sleep(random(300, 500))
        setPriceByText('初始基准价', price) && sleep(random(300, 500))
        click(text('按价格').findOnce().bounds()) && sleep(random(500, 800))
        setPriceByText('上涨-', bc) && sleep(random(300, 500))
        setPriceByText('回落-卖出', bc / 10) && sleep(random(300, 500))
        setPriceByText('下跌-', bc) && sleep(random(300, 500))
        setPriceByText('反弹-买入', bc / 10) && sleep(random(300, 500))
        click('下一步') && sleep(random(800, 1000))
        //自动判断用户交易模式 如果金额模式自动切换成数量
        var chanege_btn = id("com.hexin.plat.android:id/tv_wt_type_change").findOne()
        var lay_out = id("com.hexin.plat.android:id/price_num_change_layout").findOne()
        var btn_text = chanege_btn.getText()
        if (btn_text == "数量") {
            print("切换数量成功")
            lay_out.click();
        }
        setPriceByText('每笔委托', updateData.data.num) && sleep(random(300, 500))
        click("提交云条件单") && sleep(random(800, 1000))
        confirmOrderBeforeSubmit(bc, 0)
        changeTitle(7) && sleep(300)
        // true：自动提交订单 false：手动确认
        const doSubmit = is_auto_submit || confirm("您要提交云条件单吗?")
        if (doSubmit) {
            clickCent(id("com.hexin.plat.android:id/tv_confirm_submit"), 1200);// 最后提交功能 
            sleep(500)
            if (id("com.hexin.plat.android:id/tv_confirm_submit").exists()) {
                text1 = id("com.hexin.plat.android:id/tv_confirm_submit").findOne().text()
                if (text1 == "重新提交") {
                    return
                }
            }
        }
        return true
    }
}

function clear_stocks(){
    changeTitle(103)
    !text('条件单').boundsInside(0, device.height/2, device.width, device.height).exists() && click('交易')&&sleep(500)
    id("menu_holdings").findOne().click()&&sleep(500)
    while (true) {
        rollview =id("recyclerview_id").className("androidx.recyclerview.widget.RecyclerView").scrollable(true);
        if (rollview.exists()){ //
            var phase =className("android.widget.TextView").text("盈亏").findOne()
            phase_left =phase.bounds().left
            var stockcode = className("android.widget.TextView").text("证券代码").findOne()
            stockcode_left = stockcode.bounds().left
            id("recyclerview_id").findOne().children().forEach(child => {
                var target_content_c = child.findOne(id("content_scrollview"))
                if (target_content_c){
                    needpush = false
                    target_content_c.children().forEach(child2 => {
                        if (child2.text().includes("%")){
                            if (phase_left==child2.bounds().left){//获取盈亏票
                                if(percentageToDecimal(child2.text())>app.autoMata.profitRate){//止盈 目前只对止盈二点一键清仓
                                    needpush = true
                                }
                            }
                        }
                        if (needpush && stockcode_left==child2.bounds().left) {
                            stock_code = child2.text()
                            stock_name = child2.parent().parent().child(0).text()
                            sell_list[stock_code] = stock_name
                        }
                    });
                } else {
                    sync_iscompelte=true;
                }
            });
        } else{
            toastLog("持仓已经检查到最底部");
            sync_iscompelte=true;
        }

        if (!sync_iscompelte){
            swipeUp();
        } else {
            break;   
        }
    }

    if (sell_list.length == 0 ){//
        print("产品没有红的")
    } else {
        text("卖出").find().click()&&sleep(400)//进入卖出界面
        sell()//售卖
    }

    return true
}

/*在线更新源码*/
function onlineCheckUpdate(){
    const {version, updateRecords, downloadInfo} = app.cache.config
    const [downloadName, downloadUrl] = downloadInfo
    dialogs.build({
        title: `检查更新脚本-${version}`,
        content: updateRecords.join('\n'),
        positive: "下载到本地",
        negative: "取消",
        neutral: "到浏览器下载"
    })
    .on("positive", () => {
        app.downloadDialog = dialogs.build({
            title: "下载中...",
            negative: "取消",
            progress: {max: 100, showMinMax: true},
            autoDismiss: false
        })
        .on("negative", ()=>{app.downloadDialog.dismiss() || (app.downloadDialog = null)})
        .show()
        app.downloadDialog.setProgress(90)
        threads.start(function(){
            const {statusCode, body} =  http.get(downloadUrl)
            if (statusCode == 200) {
                const filePath = `${files.cwd()}/${downloadName}`
                files.writeBytes(filePath, body.bytes())
                toastLog('下载成功')
                app.downloadDialog.setProgress(100) || sleep(1000)
                app.downloadDialog.dismiss() || (app.downloadDialog = null)
            }
        })
    })
    .on("neutral", () => {
        app.openUrl(downloadUrl);
    })
    .show()
}

//判断文字是否存在，如果再则点击  函数
function clickCent(Word, sleepTime) {
    if (Word.findOne(1500)) {
        click(Word.findOne(1500).bounds().centerX(), Word.findOne(1500).bounds().centerY());
        sleep(sleepTime);
    }
}

//等待某个元素出现,并点击
function waitClick(word) {
    click(word.findOne().bounds().centerX(), word.findOne().bounds().centerY())
}

//向下寻找进行点击 
function findson_click(obj){
   var chids_count =obj.getChildCount();//获取子布局的数量
    // print(" chids_count ",chids_count);
    if (chids_count>0){
        obj.children().forEach(chid => {//向下寻找进行点击
            // print( "chid ",chid)
            if (chid.clickable()){
                chid.click()
            }else{//不能点击就接着找
                findson_click(chid)
            }
        })
    }
}







//向上找6级父级clickable，为true时点击
function findClick(word) {
    let findWord = word.findOne()
    for (let i = 0; i < 6; i++) {
        if (findWord.clickable()) {
            findWord.click();
            break;
        } else { findWord = findWord.parent() }
    }
}

function percentageToDecimal(percentageStr) {
  // 移除百分号并转换为浮点数
  var decimal = parseFloat(percentageStr.replace('%', ''));
  // 确保结果是有效的数字
  if (isNaN(decimal)) {
    throw new Error('输入的字符串不是一个有效的百分比');
  }
  return decimal;
}

//等待某个元素出现
function wait(word) {
    word.waitFor();
    sleep(1000);
}

//返回到初始页面
function back_click(){    
    back_times = back_times + 1;
    if (back_times > 6) {
        print("返回异常");
        toast("返回异常,程序停止，请自行返回初始页面");
        exit();
    }
    if(className("android.widget.LinearLayout").desc("取消").exists()){
        className("android.widget.LinearLayout").desc("取消").findOne().click();
        print("点击取消");
        sleep(600);
        back_click();//有取消就点击
    }
    if(id("com.hexin.plat.android:id/title_bar_img").exists()){
        id("com.hexin.plat.android:id/title_bar_img").findOne().parent().click();
        sleep(600);
        print("点击返回");
        back_click();//有返回就点击
    }
    back_times=0;
    print("返回结束");
}

function swipeUp() {
    // 获取屏幕的高度
    var screenHeight = device.height;
    // 执行一个从屏幕中间向上滑动的动作
    // 滑动距离可以根据需要调整
    swipe(device.width / 2, screenHeight * 9/ 10, device.width / 2, screenHeight /10, 200);
}

// 定义查找包含特定字符串的标签的函数
function findLabelWithText(text) {
    // 使用textContains选择器查找包含特定文本的标签
    var labels = textContains(text).find();
    return labels;
}

// 异常时将已经放在缓存里的代码回滚
function backStorageStock() {
    //出异常时将代码从缓存中删除
    if (currentStock != 0 && currentType != '') {
        if (currentType == "stock") {
            app.autoMata.stocks = app.autoMata.stocks.filter(function(item) {
                return item !== currentStock
            });
        }else if(currentType == "fund"){
            app.autoMata.funds = app.autoMata.funds.filter(function(item) {
                return item !== currentStock
            });
        }else if(currentType == "bond"){
            app.autoMata.bonds = app.autoMata.bonds.filter(function(item) {
                return item !== currentStock
            });
        }
        currentStock = 0
        currentType = ''
    }
}